package com.blb.missiom.filter;


import com.blb.missiom.service.IUserService;
import com.blb.missiom.util.ApplicationContextUtils;
import com.blb.missiom.util.JwtUtils;
import com.blb.missiom.util.RsaUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author lvtian
 * @date 2023/2/1 17:02
 * 请求验证过滤器
 */
@Slf4j
public class RequestAuthenticationFilter extends BasicAuthenticationFilter {
    public static final String AUTH_HEADER = "Authorization";

    //通过工具类获得service对象
    private IUserService userService = ApplicationContextUtils.getBean(IUserService.class);

    public RequestAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }
    //请求的过滤
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //从请求头获得token
        String token = request.getHeader(AUTH_HEADER);
        if(StringUtils.isEmpty(token)){
            //从请求参数获得token
            token = request.getParameter(AUTH_HEADER);
        }
        //如果读取不到，就拦截
        if(StringUtils.isEmpty(token)){
            log.info("读取不到token，请求{}被拦截",request.getRequestURL());
            chain.doFilter(request,response);
            return;
        }
        try {
            //对token进行解析
            String username = JwtUtils.getUsernameFromToken(token, RsaUtils.publicKey);
            //将用户的权限查询出来
            List<String> authList = userService.getAuthoritiesByUsername(username);
            List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",", authList));
            //创建通行证
            UsernamePasswordAuthenticationToken authToken = new
                    UsernamePasswordAuthenticationToken(username,"",authorities);
            //把通行证交给Security
            SecurityContextHolder.getContext().setAuthentication(authToken);
        }catch (Exception ex){
            log.error("解析token失败",ex);
        }
        chain.doFilter(request,response);
    }
}
